package Bench::Test::Local;

use 5.008004;
use strict;
use warnings;

use Cwd;
use File::Basename;

our $VERSION = '0.01';

our $GET_RESULT  = \&default_get_result;
our $SAVE_RESULT = \&default_save_result;

sub error_no_param {
   my $param = shift;
   die "You must set " . $param . " parameter in " . __PACKAGE__ . " constructor\n";
}

#============================================================================== 
# Object Constructor.
#============================================================================== 
sub new {
   my ($class, %params) = @_;
  
   my $workdir    = $params{WORKDIR}    or error_no_param("WORKDIR");
   my $executable = $params{EXECUTABLE} or error_no_param("EXECUTABLE");

   die "Error trying to change to $workdir\n" unless (-d $workdir);

   return bless {
      CURRENTDIR  => cwd, 
      WORKDIR     => $workdir,
      EXECUTABLE  => $executable,
      BASEDIR     => $params{BASEDIR},
      PREAMBLE    => $params{PREAMBLE}    || sub { 1 },
      POSTAMBLE   => $params{POSTAMBLE}   || sub { 1 },
      GET_RESULT  => $params{GET_RESULT}  || $GET_RESULT,
      SAVE_RESULT => $params{SAVE_RESULT} || $SAVE_RESULT,
      OUTPUTFILE  => $params{OUTPUTFILE},
   }, $class;
}

sub execute_preamble {
   my $self = shift;
   $self->{PREAMBLE}->();
}

sub execute_postamble {
   my $self = shift;
   $self->{POSTAMBLE}->();
}

sub get_result {
   return $_[0]->{GET_RESULT}->(@_);
}

sub default_get_result {
   my ($self, $params) = (shift, shift);

   chdir $self->{WORKDIR};

   my $executable = $self->{EXECUTABLE};

   my $output = `$executable $params`;

   die "An error ocurred when trying to execute '$executable $params'\n"
      if ($?);

   if (my $outputfile = $self->{OUTPUTFILE}) {
      local $/ = undef;
      open OF, "< $outputfile"
         or die "An error ocurred when trying to read OUTPUTFILE: '$outputfile'\n";
      $output = <OF>;
      close OF
         or die "An error ocurred when trying to close OUTPUTFILE: '$outputfile'\n";

      unlink $outputfile;
   }
   chdir $self->{CURRENTDIR};

   return $output;
}

sub save_result {
   return $_[0]->{SAVE_RESULT}->(@_);
}

sub default_save_result {
   my ($self, $params, $test) = @_;

   my $output = $self->get_result($params);

   if (not -d $self->{BASEDIR}) {
     mkdir $self->{BASEDIR};
     print "Creating directory for base files: " . $self->{BASEDIR} . "\n";
   }

   chdir $self->{BASEDIR};

   open BASEFILE, "> $test.base";
   print BASEFILE $output;
   close BASEFILE;

   print "Created " . $self->{BASEDIR} . "/$test.base\n";

   chdir $self->{CURRENTDIR};
}
